<!doctype html>
<head>
  <style>
    body {
      font-family: sans-serif;
      color: #333333;
    }

    .demo, .noedit {
      font-family: monospace;
      font-size  : 14px;
      padding    : 2px;
      margin     : 0px;
      border: 1px solid #ccc;
      display    : inline-block;
      border-radius: 3px;
    }

    .demoInput {
      background-color: rgb(255, 255, 244);
    }
    .demoOutput {
      background-color: rgb(172, 243, 172);
    }
    .demoError {
      background-color: rgb(248, 151, 151);
    }
    .demoNull {
      background-color: rgb(224, 203, 149);
    }
    .demoIO, .noedit {
      border: 1px solid #ccc;
      border-radius: 3px;
      display: inline-block;
      padding: 5px;
      background-color: #f8f8f8;
    }
    .noedit {
      display: block;
    }

    .markdown {
      display: inline-block;
      background: #fff;
      border-radius: 3px;
      padding: 3px;
      font-size: 14px;
      line-height: 1.6;
      font: 13px Helvetica, arial, freesans, clean, sans-serif;
      border: 1px solid #CACACA;
      margin: 0px auto auto;
      padding: 0px 30px 0px 30px;
      text-align: left;
    }

    .markdown p {
      max-width: 600px;
    }

    #centerer {
      text-align: center;
      padding: 0px;
      margin: 0px;
    }

    .markdown>h2, .markdown>h3,
    .markdown>h4, .markdown>h5, .markdown>h6 {
      border-bottom: 1px solid #ccc;
    }

    .container {
      padding: 3px;
      background: #EEE;
      border-radius: 3px;
      margin: 0px;
      display: inline-block;
      margin-bottom: 200px;
    }

    #footer {
      font-size: 10px;
      text-align: center;
    }

  </style>
  <script>var require = function (file, cwd) {
    var resolved = require.resolve(file, cwd || '/');
    var mod = require.modules[resolved];
    if (!mod) throw new Error(
        'Failed to resolve module ' + file + ', tried ' + resolved
    );
    var cached = require.cache[resolved];
    var res = cached? cached.exports : mod();
    return res;
};

require.paths = [];
require.modules = {};
require.cache = {};
require.extensions = [".js",".coffee",".json"];

require._core = {
    'assert': true,
    'events': true,
    'fs': true,
    'path': true,
    'vm': true
};

require.resolve = (function () {
    return function (x, cwd) {
        if (!cwd) cwd = '/';
        
        if (require._core[x]) return x;
        var path = require.modules.path();
        cwd = path.resolve('/', cwd);
        var y = cwd || '/';
        
        if (x.match(/^(?:\.\.?\/|\/)/)) {
            var m = loadAsFileSync(path.resolve(y, x))
                || loadAsDirectorySync(path.resolve(y, x));
            if (m) return m;
        }
        
        var n = loadNodeModulesSync(x, y);
        if (n) return n;
        
        throw new Error("Cannot find module '" + x + "'");
        
        function loadAsFileSync (x) {
            x = path.normalize(x);
            if (require.modules[x]) {
                return x;
            }
            
            for (var i = 0; i < require.extensions.length; i++) {
                var ext = require.extensions[i];
                if (require.modules[x + ext]) return x + ext;
            }
        }
        
        function loadAsDirectorySync (x) {
            x = x.replace(/\/+$/, '');
            var pkgfile = path.normalize(x + '/package.json');
            if (require.modules[pkgfile]) {
                var pkg = require.modules[pkgfile]();
                var b = pkg.browserify;
                if (typeof b === 'object' && b.main) {
                    var m = loadAsFileSync(path.resolve(x, b.main));
                    if (m) return m;
                }
                else if (typeof b === 'string') {
                    var m = loadAsFileSync(path.resolve(x, b));
                    if (m) return m;
                }
                else if (pkg.main) {
                    var m = loadAsFileSync(path.resolve(x, pkg.main));
                    if (m) return m;
                }
            }
            
            return loadAsFileSync(x + '/index');
        }
        
        function loadNodeModulesSync (x, start) {
            var dirs = nodeModulesPathsSync(start);
            for (var i = 0; i < dirs.length; i++) {
                var dir = dirs[i];
                var m = loadAsFileSync(dir + '/' + x);
                if (m) return m;
                var n = loadAsDirectorySync(dir + '/' + x);
                if (n) return n;
            }
            
            var m = loadAsFileSync(x);
            if (m) return m;
        }
        
        function nodeModulesPathsSync (start) {
            var parts;
            if (start === '/') parts = [ '' ];
            else parts = path.normalize(start).split('/');
            
            var dirs = [];
            for (var i = parts.length - 1; i >= 0; i--) {
                if (parts[i] === 'node_modules') continue;
                var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
                dirs.push(dir);
            }
            
            return dirs;
        }
    };
})();

require.alias = function (from, to) {
    var path = require.modules.path();
    var res = null;
    try {
        res = require.resolve(from + '/package.json', '/');
    }
    catch (err) {
        res = require.resolve(from, '/');
    }
    var basedir = path.dirname(res);
    
    var keys = (Object.keys || function (obj) {
        var res = [];
        for (var key in obj) res.push(key);
        return res;
    })(require.modules);
    
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        if (key.slice(0, basedir.length + 1) === basedir + '/') {
            var f = key.slice(basedir.length);
            require.modules[to + f] = require.modules[basedir + f];
        }
        else if (key === basedir) {
            require.modules[to] = require.modules[basedir];
        }
    }
};

(function () {
    var process = {};
    var global = typeof window !== 'undefined' ? window : {};
    var definedProcess = false;
    
    require.define = function (filename, fn) {
        if (!definedProcess && require.modules.__browserify_process) {
            process = require.modules.__browserify_process();
            definedProcess = true;
        }
        
        var dirname = require._core[filename]
            ? ''
            : require.modules.path().dirname(filename)
        ;
        
        var require_ = function (file) {
            var requiredModule = require(file, dirname);
            var cached = require.cache[require.resolve(file, dirname)];

            if (cached && cached.parent === null) {
                cached.parent = module_;
            }

            return requiredModule;
        };
        require_.resolve = function (name) {
            return require.resolve(name, dirname);
        };
        require_.modules = require.modules;
        require_.define = require.define;
        require_.cache = require.cache;
        var module_ = {
            id : filename,
            filename: filename,
            exports : {},
            loaded : false,
            parent: null
        };
        
        require.modules[filename] = function () {
            require.cache[filename] = module_;
            fn.call(
                module_.exports,
                require_,
                module_,
                module_.exports,
                dirname,
                filename,
                process,
                global
            );
            module_.loaded = true;
            return module_.exports;
        };
    };
})();


require.define("path",Function(['require','module','exports','__dirname','__filename','process','global'],"function filter (xs, fn) {\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        if (fn(xs[i], i, xs)) res.push(xs[i]);\n    }\n    return res;\n}\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = parts.length; i >= 0; i--) {\n    var last = parts[i];\n    if (last == '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Regex to split a filename into [*, dir, basename, ext]\n// posix version\nvar splitPathRe = /^(.+\\/(?!$)|\\/)?((?:.+?)?(\\.[^.]*)?)$/;\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\nvar resolvedPath = '',\n    resolvedAbsolute = false;\n\nfor (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {\n  var path = (i >= 0)\n      ? arguments[i]\n      : process.cwd();\n\n  // Skip empty and invalid entries\n  if (typeof path !== 'string' || !path) {\n    continue;\n  }\n\n  resolvedPath = path + '/' + resolvedPath;\n  resolvedAbsolute = path.charAt(0) === '/';\n}\n\n// At this point the path should be resolved to a full absolute path, but\n// handle relative paths to be safe (might happen when process.cwd() fails)\n\n// Normalize the path\nresolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n    return !!p;\n  }), !resolvedAbsolute).join('/');\n\n  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\nvar isAbsolute = path.charAt(0) === '/',\n    trailingSlash = path.slice(-1) === '/';\n\n// Normalize the path\npath = normalizeArray(filter(path.split('/'), function(p) {\n    return !!p;\n  }), !isAbsolute).join('/');\n\n  if (!path && !isAbsolute) {\n    path = '.';\n  }\n  if (path && trailingSlash) {\n    path += '/';\n  }\n  \n  return (isAbsolute ? '/' : '') + path;\n};\n\n\n// posix version\nexports.join = function() {\n  var paths = Array.prototype.slice.call(arguments, 0);\n  return exports.normalize(filter(paths, function(p, index) {\n    return p && typeof p === 'string';\n  }).join('/'));\n};\n\n\nexports.dirname = function(path) {\n  var dir = splitPathRe.exec(path)[1] || '';\n  var isWindows = false;\n  if (!dir) {\n    // No dirname\n    return '.';\n  } else if (dir.length === 1 ||\n      (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {\n    // It is just a slash or a drive letter with a slash\n    return dir;\n  } else {\n    // It is a full dirname, strip trailing slash\n    return dir.substring(0, dir.length - 1);\n  }\n};\n\n\nexports.basename = function(path, ext) {\n  var f = splitPathRe.exec(path)[2] || '';\n  // TODO: make this comparison case-insensitive on windows?\n  if (ext && f.substr(-1 * ext.length) === ext) {\n    f = f.substr(0, f.length - ext.length);\n  }\n  return f;\n};\n\n\nexports.extname = function(path) {\n  return splitPathRe.exec(path)[3] || '';\n};\n\nexports.relative = function(from, to) {\n  from = exports.resolve(from).substr(1);\n  to = exports.resolve(to).substr(1);\n\n  function trim(arr) {\n    var start = 0;\n    for (; start < arr.length; start++) {\n      if (arr[start] !== '') break;\n    }\n\n    var end = arr.length - 1;\n    for (; end >= 0; end--) {\n      if (arr[end] !== '') break;\n    }\n\n    if (start > end) return [];\n    return arr.slice(start, end - start + 1);\n  }\n\n  var fromParts = trim(from.split('/'));\n  var toParts = trim(to.split('/'));\n\n  var length = Math.min(fromParts.length, toParts.length);\n  var samePartsLength = length;\n  for (var i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  var outputParts = [];\n  for (var i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n};\n\n//@ sourceURL=path"
));

require.define("__browserify_process",Function(['require','module','exports','__dirname','__filename','process','global'],"var process = module.exports = {};\n\nprocess.nextTick = (function () {\n    var canSetImmediate = typeof window !== 'undefined'\n        && window.setImmediate;\n    var canPost = typeof window !== 'undefined'\n        && window.postMessage && window.addEventListener\n    ;\n\n    if (canSetImmediate) {\n        return function (f) { return window.setImmediate(f) };\n    }\n\n    if (canPost) {\n        var queue = [];\n        window.addEventListener('message', function (ev) {\n            if (ev.source === window && ev.data === 'browserify-tick') {\n                ev.stopPropagation();\n                if (queue.length > 0) {\n                    var fn = queue.shift();\n                    fn();\n                }\n            }\n        }, true);\n\n        return function nextTick(fn) {\n            queue.push(fn);\n            window.postMessage('browserify-tick', '*');\n        };\n    }\n\n    return function nextTick(fn) {\n        setTimeout(fn, 0);\n    };\n})();\n\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\n\nprocess.binding = function (name) {\n    if (name === 'evals') return (require)('vm')\n    else throw new Error('No such module. (Possibly not yet loaded)')\n};\n\n(function () {\n    var cwd = '/';\n    var path;\n    process.cwd = function () { return cwd };\n    process.chdir = function (dir) {\n        if (!path) path = require('path');\n        cwd = path.resolve(dir, cwd);\n    };\n})();\n\n//@ sourceURL=__browserify_process"
));

require.define("/node_modules/hyperscript/node_modules/hyperscript/package.json",Function(['require','module','exports','__dirname','__filename','process','global'],"module.exports = {}\n//@ sourceURL=/node_modules/hyperscript/node_modules/hyperscript/package.json"
));

require.define("/node_modules/hyperscript/index.js",Function(['require','module','exports','__dirname','__filename','process','global'],";(function () {\n\nvar ClassList = require(\"class-list\")\n\nfunction h() {\n  var args = [].slice.call(arguments), e = null\n  function item (l) {\n    var r\n    function parseClass (string) {\n      var m = string.split(/([\\.#]?[a-zA-Z0-9_-]+)/)\n      m.forEach(function (v) {\n        var s = v.substring(1,v.length)\n        if(!v) return\n        if(!e)\n          e = document.createElement(v)\n        else if (v[0] === '.')\n          ClassList(e).add(s)\n        else if (v[0] === '#')\n          e.setAttribute('id', s)\n      })\n    }\n\n    if(l == null)\n      ;\n    else if('string' === typeof l) {\n      if(!e)\n        parseClass(l)\n      else\n        e.appendChild(r = document.createTextNode(l))\n    }\n    else if('number' === typeof l\n      || 'boolean' === typeof l\n      || l instanceof Date\n      || l instanceof RegExp ) {\n        e.appendChild(r = document.createTextNode(l.toString()))\n    }\n    //there might be a better way to handle this...\n    else if (Array.isArray(l))\n      l.forEach(item)\n    else if(l instanceof Node)\n      e.appendChild(r = l)\n    else if(l instanceof Text)\n      e.appendChild(r = l)\n    else if ('object' === typeof l) {\n      for (var k in l) {\n        if('function' === typeof l[k]) {\n          if(/^on\\w+/.test(k)) {\n            e.addEventListener(k.substring(2), l[k])\n          } else {\n            e[k] = l[k]()\n            l[k](function (v) {\n              e[k] = v\n            })\n          }\n        }\n        else if(k === 'style') {\n          for (var s in l[k]) (function(s, v) {\n            if('function' === typeof v) {\n              e.style.setProperty(s, v())\n              v(function (val) {\n                e.style.setProperty(s, val)\n              })\n            } else\n              e.style.setProperty(s, l[k][s])\n          })(s, l[k][s])\n        } else\n          e[k] = l[k]\n      }\n    } else if ('function' === typeof l) {\n      //assume it's an observable!\n      var v = l()\n      e.appendChild(r = v instanceof Node ? v : document.createTextNode(v))\n\n      l(function (v) {\n        if(v instanceof Node && r.parentElement)\n          r.parentElement.replaceChild(v, r), r = v\n        else\n          r.textContent = v\n      })\n\n    }\n\n    return r\n  }\n  while(args.length)\n    item(args.shift())\n\n  return e\n}\n\nif(typeof module === 'object')\n module.exports = h\nelse\n  this.hyperscript = h\n})()\n\n//@ sourceURL=/node_modules/hyperscript/index.js"
));

require.define("/node_modules/hyperscript/node_modules/class-list/package.json",Function(['require','module','exports','__dirname','__filename','process','global'],"module.exports = {\"main\":\"index\"}\n//@ sourceURL=/node_modules/hyperscript/node_modules/class-list/package.json"
));

require.define("/node_modules/hyperscript/node_modules/class-list/index.js",Function(['require','module','exports','__dirname','__filename','process','global'],"// contains, add, remove, toggle\n\nmodule.exports = ClassList\n\nfunction ClassList(elem) {\n    var cl = elem.classList\n\n    if (cl) {\n        return cl\n    }\n\n    var classList = {\n        add: add\n        , remove: remove\n        , contains: contains\n        , toggle: toggle\n        , toString: $toString\n        , length: 0\n        , item: item\n    }\n\n    return classList\n\n    function add(token) {\n        var list = getTokens()\n        if (list.indexOf(token) > -1) {\n            return\n        }\n        list.push(token)\n        setTokens(list)\n    }\n\n    function remove(token) {\n        var list = getTokens()\n            , index = list.indexOf(token)\n\n        if (index === -1) {\n            return\n        }\n\n        list.splice(index, 1)\n        setTokens(list)\n    }\n\n    function contains(token) {\n        return getTokens().indexOf(token) > -1\n    }\n\n    function toggle(token) {\n        if (contains(token)) {\n            remove(token)\n            return false\n        } else {\n            add(token)\n            return true\n        }\n    }\n\n    function $toString() {\n        return elem.className\n    }\n\n    function item(index) {\n        var tokens = getTokens()\n        return tokens[index] || null\n    }\n\n    function getTokens() {\n        var className = elem.className\n\n        return className.split(\" \").filter(isTruthy)\n    }\n\n    function setTokens(list) {\n        var length = list.length\n\n        elem.className = list.join(\" \")\n        classList.length = length\n\n        for (var i = 0; i < list.length; i++) {\n            classList[i] = list[i]\n        }\n\n        delete list[length]\n    }\n}\n\nfunction isTruthy(value) {\n    return !!value\n}\n//@ sourceURL=/node_modules/hyperscript/node_modules/class-list/index.js"
));

require.define("/tmp.js",Function(['require','module','exports','__dirname','__filename','process','global'],"var funx = [\nfunction () {\nvar h = require('hyperscript')\nh('div#page',\n  h('div#header',\n    h('h1.classy', 'h', { style: {'background-color': '#22f'} })),\n  h('div#menu', { style: {'background-color': '#2f2'} },\n    h('ul',\n      h('li', 'one'),\n      h('li', 'two'),\n      h('li', 'three'))),\n    h('h2', 'content title',  { style: {'background-color': '#f22'} }),\n    h('p', \n      \"so it's just like a templating engine,\\n\",\n      \"but easy to use inline with javascript\\n\"),\n    h('p', \n      \"the intention is for this to be used to create\\n\",\n      \"reusable, interactive html widgets. \"))\n},\nfunction () {\nvar h = require('hyperscript')\nh('a', {href: 'https://npm.im/hyperscript'}, 'hyperscript')\n},\nfunction () {\nvar h = require('hyperscript')\nh('a', {href: '#', \n  onclick: function (e) {\n    alert('you are 1,000,000th visitor!')\n    e.preventDefault()\n  }\n}, 'click here to win a prize')\n},\nfunction () {\nvar h = require('hyperscript')\nh('h1.fun', {style: {'font-family': 'Comic Sans MS'}}, 'Happy Birthday!')\n},\nfunction () {\nvar h = require('hyperscript')\nvar obj = {\n  a: 'Apple',\n  b: 'Banana',\n  c: 'Cherry',\n  d: 'Durian',\n  e: 'Elder Berry'\n}\nh('table',\n  h('tr', h('th', 'letter'), h('th', 'fruit')),\n  Object.keys(obj).map(function (k) {\n    return h('tr', \n      h('th', k),\n      h('td', obj[k])\n    )\n  })\n)\n}\n];\n\n//@ sourceURL=/tmp.js"
));
require("/tmp.js");

</script>
</head>
<body>
  <div id=centerer>
    <div class=container><div class=markdown>
      <h1>HyperScript</h1>
<p>Create HyperText with JavaScript.</p>
<p><a href="http://dominictarr.github.com/hyperscript">Interactive Demo</a></p>
<h2>Example</h2>
<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
h(&#39;div#page&#39;,
  h(&#39;div#header&#39;,
    h(&#39;h1.classy&#39;, &#39;h&#39;, { style: {&#39;background-color&#39;: &#39;#22f&#39;} })),
  h(&#39;div#menu&#39;, { style: {&#39;background-color&#39;: &#39;#2f2&#39;} },
    h(&#39;ul&#39;,
      h(&#39;li&#39;, &#39;one&#39;),
      h(&#39;li&#39;, &#39;two&#39;),
      h(&#39;li&#39;, &#39;three&#39;))),
    h(&#39;h2&#39;, &#39;content title&#39;,  { style: {&#39;background-color&#39;: &#39;#f22&#39;} }),
    h(&#39;p&#39;, 
      &quot;so it&#39;s just like a templating engine,\n&quot;,
      &quot;but easy to use inline with javascript\n&quot;),
    h(&#39;p&#39;, 
      &quot;the intention is for this to be used to create\n&quot;,
      &quot;reusable, interactive html widgets. &quot;))</code></pre>
<h2>h (tag, attrs, [text?, Elements?,...])</h2>
<p>Create an <code>HTMLElement</code>. first argument must be the tag name.</p>
<h3>classes &amp; id</h3>
<p>If the tag name is of form <code>name.class1.class2#id</code> that is a short cut
for setting the class and id.</p>
<h3>Attributes</h3>
<p>If an <code>{}</code> object is passed in, it&#39;s values will be used to set attributes.</p>
<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
h(&#39;a&#39;, {href: &#39;https://npm.im/hyperscript&#39;}, &#39;hyperscript&#39;)</code></pre>
<h3>events</h3>
<p>If an attribute is a function, then it will be registered as an event listener.</p>
<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
h(&#39;a&#39;, {href: &#39;#&#39;, 
  onclick: function (e) {
    alert(&#39;you are 1,000,000th visitor!&#39;)
    e.preventDefault()
  }
}, &#39;click here to win a prize&#39;)</code></pre>
<h3>styles</h3>
<p>If an attribute has a style property, then that will be handled specially.</p>
<pre><code class="lang-js">var h = require(&#39;hyperscript&#39;)
h(&#39;h1.fun&#39;, {style: {&#39;font-family&#39;: &#39;Comic Sans MS&#39;}}, &#39;Happy Birthday!&#39;)</code></pre>
<p>You may pass in attributes in multiple positions, it&#39;s no problem!</p>
<h3>children - string</h3>
<p>If an argument is a string, a TextNode is created in that position.</p>
<h3>children - HTMLElement</h3>
<p>If a argument is a <code>Node</code> (or <code>HTMLElement</code>), for example, the return value of a call to <code>h</code>
thats cool too.</p>
<h3>children - null.</h3>
<p>This is just ignored.</p>
<h3>children - Array</h3>
<p>Each item in the array is treated like a ordinary child. (string or HTMLElement)
this is uesful when you want to iterate over an object:</p>
<pre><code>var h = require(&#39;hyperscript&#39;)
var obj = {
  a: &#39;Apple&#39;,
  b: &#39;Banana&#39;,
  c: &#39;Cherry&#39;,
  d: &#39;Durian&#39;,
  e: &#39;Elder Berry&#39;
}
h(&#39;table&#39;,
  h(&#39;tr&#39;, h(&#39;th&#39;, &#39;letter&#39;), h(&#39;th&#39;, &#39;fruit&#39;)),
  Object.keys(obj).map(function (k) {
    return h(&#39;tr&#39;, 
      h(&#39;th&#39;, k),
      h(&#39;td&#39;, obj[k])
    )
  })
)</code></pre>
<h2>License</h2>
<p>MIT</p>

    </div></div>
  </div>
<div id=footer>
created with <a href=https://github.com/dominictarr/demonstrate>demonstrate</a>
</div>
  <script>;(function () {
;(function () {

function h() {
  var args = [].slice.call(arguments), e = null
  function item (l) {
    var r
    function parseClass (string) {
      var m = string.split(/([\.#]?[a-zA-Z0-9_-]+)/)
      m.forEach(function (v) {
        var s = v.substring(1,v.length)
        if(!v) return 
        if(!e)
          e = document.createElement(v)
        else if (v[0] === '.')
          e.classList.add(s)
        else if (v[0] === '#')
          e.setAttribute('id', s)
      })
    }

    if(l == null)
      ;
    else if('string' === typeof l) {
      if(!e)
        parseClass(l)
      else
        e.appendChild(r = document.createTextNode(l))
    }
    else if('number' === typeof l 
      || 'boolean' === typeof l
      || l instanceof Date 
      || l instanceof RegExp ) {
        e.appendChild(r = document.createTextNode(l.toString()))
    }
    //there might be a better way to handle this...
    else if (Array.isArray(l))
      l.forEach(item)
    else if(l instanceof Node)
      e.appendChild(r = l)
    else if(l instanceof Text)
      e.appendChild(r = l)
    else if ('object' === typeof l) {
      for (var k in l) {
        if('function' === typeof l[k]) {
          if(/^on\w+/.test(k)) {
            e.addEventListener(k, l[k])
          } else {
            e[k] = l[k]()
            l[k](function (v) {
              e[k] = v
            })
          }
        }
        else if(k === 'style') {
          for (var s in l[k]) (function(s, v) {
            if('function' === typeof v) {
              e.style.setProperty(s, v())
              v(function (val) {
                e.style.setProperty(s, val)
              })
            } else
              e.style.setProperty(s, l[k][s])
          })(s, l[k][s])
        } else
          e[k] = l[k]
      }
    } else if ('function' === typeof l) {
      //assume it's an observable!
      var v = l()
      e.appendChild(r = v instanceof Node ? v : document.createTextNode(v))

      l(function (v) {
        if(v instanceof Node && r.parentElement)
          r.parentElement.replaceChild(v, r), r = v
        else
          r.textContent = v
      })
      
    }

    return r
  }
  while(args.length)
    item(args.shift())

  return e
}

if(typeof module === 'object')
 module.exports = h
else
  this.hyperscript = h
})()
;(function () {

//---util-funtions------

function all(ary, val) {
  for(var k in ary)
    ary[k](val)
}

function remove(ary, item) {
  delete ary[ary.indexOf(item)]  
}

/*
##value
An observable that stores a value.
*/

function value () {
  var _val, listeners = []
  return function (val) {
    return (
      get(val) ? _val
    : set(val) ? all(listeners, _val = val)
    : (listeners.push(val), function () {
        remove(listeners, val)
      })
  )}}

/*
##property
observe a property of an object, works with scuttlebutt.
could change this to work with backbone Model - but it would become ugly.
*/

function get(val) {
  //void(0) is a trick to get a true undefined value, even if user has overwrit
  return undefined === val
}

/*
### set(val) _(private)_
return true if this call is a set (a non function is supplied)
set(val) assumes you have already checked get(val)
if the call is neither a get or a set, a function is passed, it's a listen.
*/

function set(val) {
  return 'function' !== typeof val
}

/*
now, lets rewrite our first example
*/

function property (model, key) {
  return function (val) {
    return (
      get(val) ? model.get(key) :
      set(val) ? model.set(key, val) :
      (model.on('change:'+key, val), function () {
        model.removeListener('change:'+key, val)
      })
    )}}
    //^ if written in this style, always ends )}}

/*
note the use of the elvis operator `?:` in chained else-if formation,
and also the comma operator `,` which evaluates each part and then
returns the last value.

only 8 lines! that isn't much for what this baby can do!
*/

function transform (observable, down, up) {
  return function (val) {
    return (
      get(val) ? down(observable())
    : set(val) ? observable((up || down)(val))
    : observable(function (_val) { val(down(_val)) })
    )}}

function not(observable) {
  return transform(observable, function (v) { return !v })
}

function listen (element, event, attr, listener) {
  function onEvent () {
    listener(element[attr])
  }
  element.addEventListener(event, onEvent, false)
  return function () {
    element.removeEventListener(event, onEvent, false)
  }
}

function attribute(element, attr, event) {
  attr = attr || 'value'; event = event || 'input'
  return function (val) {
    return (
      get(val) ? element[attr]
    : set(val) ? element[attr] = val
    : listen(element, event, attr, val)
    )}}


function html (element) {
  return attribute(element, 'innerHTML', false) //read only
}

function error (message) {
  throw new Error(message)
}

function compute (observables, compute) {
  function getAll() {
    return compute.apply(null, observables.map(function (e) {return e()}))
  }
  return function (val) {
    return (
      get(val) ? getAll()
    : set(val) ? error('read-only')
    : observables.forEach(function (obs) {
        obs(function () { val(getAll()) })
      })
    )}}

function boolean (observable, truthy, falsey) {
  return transform(observable, function (val) {
      return val ? truthy : falsey
    }, function (val) {
      return val == truthy ? true : false
    })
  }

var exports = value

exports.value     = value
exports.not       = not
exports.input     =
exports.attribute = attribute
exports.html      = html
exports.compute   = compute
exports.transform = transform
exports.boolean   = boolean

if('object' === typeof module) module.exports = exports
else                           this.observable = exports
})()
var h = hyperscript
var o = observable
var a = [].slice.call(document.body.getElementsByTagName('pre'))

a.filter(function (e) {
  return !~[].slice.call(e.classList).indexOf('noedit')
}).forEach(function (e) {

  var textarea
  var demo = 
    h('div.demoIO', 
      textarea = h('textarea.demo.demoInput', 
        {cols: 80, rows: e.innerText.split('\n').length + 1}, 
        e.innerText),
      h('div', o.transform(o.input(textarea), function (code) {
          try         { 
            var r = eval(code) 
            if(r instanceof Node) 
              return r
            if(r == null)
              return h('pre.demo.demoNull', r === null ? 'null' : 'undefined')

            return h('pre.demo.demoOutput', r)
          } 
          catch (err) { return h('pre.demo.demoError', err.toString()) }
        })
      )
    )

  //no scrolling!
  //It's much nicer to just resize the textarea to fit

  o.input(textarea)(function (v) {
    textarea.rows = v.split('\n').length + 1
  })

  e.parentElement.replaceChild(demo, e)


})

;})();
</script>
</body>
</html>

